﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Planer.Model.Validators;

namespace Planer.Model
{
    public class AllocationModel
    {
        static AllocationModel model = null;

        protected AllocationModel()
        {
            
        }

        public static AllocationModel GetInstance()
        {
            if (model == null)
            {
                model = new AllocationModel();
            }

            return model;
        }

        public ModelResult SaveOrUpdateAllocation(allocation Alloc)
        {
            AllocationValidator validator = new AllocationValidator();
            validator.Validate(Alloc);
            if (validator.Status == OperationStatusType.ERROR)
            {
                return new ModelResult(validator.Errors);
            }
            if (Alloc.id == 0)
            {
                Program.Db.AddToallocations(Alloc);
                if (PeriodModel.CompareShortDates(DateTime.Now, Alloc.apply_date) >= 0)
                {
                    CommitTransaction(Alloc, Alloc.apply_date);
                }
            }

            Program.Db.SaveChanges();
            return new ModelResult();
        }

        public List<allocation> GetAllocationsForGoalsByBilling(billing Bill)
        {
            List<allocation> result = new List<allocation>();
            period p = PeriodModel.GetInstance().GetCurrentPeriod();
            var query = from pact in Program.Db.allocations
                        .Include("billing")
                        .Include("allocation_transanction")
                        where pact.billing.id == Bill.id && pact.is_active == "y" && pact.accumulation == null || 
                        pact.allocation_transanction.Any(x => x.period.id == p.id)
                        select pact;

            result.AddRange(query.ToArray<allocation>());

            return result;
        }

        public List<allocation> GetAllocationsByUser(user User)
        {
            List<allocation> result = new List<allocation>();
            period p = PeriodModel.GetInstance().GetCurrentPeriod();
            var query = from pact in Program.Db.allocations
                        .Include("billing")
                        .Include("allocation_transanction")
                        where pact.billing.user.id == User.id && pact.is_active == "y" && pact.accumulation == null ||
                        pact.allocation_transanction.Any(x => x.period.id == p.id)
                        select pact;

            result.AddRange(query.ToArray<allocation>());

            return result;
        }

        public ModelResult CommitTransaction(allocation Allocation, DateTime date)
        {
            allocation_transanction transact = new allocation_transanction()
            {
                allocation = Allocation,
                create_date = date,
                mustbe_date = date,
                period = PeriodModel.GetInstance().GetCurrentPeriod(),                
            };

            return BillingModel.GetInstance().MoneyOperation(Allocation.billing, transact);
        }

        public allocation GetAllocationForAccumulationByBilling(billing Bill)
        {
            period p = PeriodModel.GetInstance().GetCurrentPeriod();
            var query = from pact in Program.Db.allocations
                        .Include("billing")
                        .Include("allocation_transanction")
                        where pact.billing.id == Bill.id && pact.is_active == "y" && pact.accumulation != null ||
                        pact.allocation_transanction.Any(x => x.period.id == p.id)
                        select pact;
            if (query.Count() == 0)
            {
                //нет отчислений - создаем нулевое
                allocation alloc = new allocation()
                {
                    accumulation = AccumulationModel.GetInstance().GetAccumulationByUser(Bill.user),
                    amount = 0,
                    apply_date = DateTime.Now,
                    billing = Bill,
                    create_date = DateTime.Now,
                    days = 0,
                    months = 1,
                    years = 0,
                    is_active = "y"                    
                };
                SaveOrUpdateAllocation(alloc);
                return alloc;
            }
            return query.First();
        }
    }
}
